package com.lcf.system.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.enums.RedisLockPrefixEnum;
import com.lcf.framework.exception.SysException;
import com.lcf.framework.utils.RedisLockUtils;
import com.lcf.framework.utils.UserUtils;
import com.lcf.framework.vo.PageVO;
import com.lcf.system.dao.SysUserDao;
import com.lcf.system.dto.user.SysUserDTO;
import com.lcf.system.dto.user.SysUserEditDTO;
import com.lcf.system.dto.user.SysUserPasswordDTO;
import com.lcf.system.entity.SysTenantUser;
import com.lcf.system.entity.SysUser;
import com.lcf.system.enums.SysRoleEnum;
import com.lcf.system.enums.UserStatusEnum;
import com.lcf.system.manager.SysUserManager;
import com.lcf.system.query.user.SysUserPageQuery;
import com.lcf.system.service.SysUserService;
import com.lcf.system.vo.user.SysUserVO;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 用户表(User)表服务实现类
 *
 * @author lcf
 * @since 2025-02-19 13:27:56
 */
@Service("userService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements SysUserService {
    @Resource
    private SysUserManager sysUserManager;
    @Resource
    private RedisLockUtils redisLockUtils;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysUserDTO dto) {
        SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
        sysUser.setPassword(UserUtils.passwordEncrypt(dto.getPassword()));
        if (dto.getRoleCode() == SysRoleEnum.ADMIN || dto.getRoleCode() == SysRoleEnum.LEADER) {
            sysUser.setStatus(UserStatusEnum.AUDITING.getCode());
        } else {
            sysUser.setStatus(UserStatusEnum.PASS.getCode());
        }

        if (dto.getRoleCode() == SysRoleEnum.LEADER && dto.getTenantId() == null) {
            throw new SysException("请选择社区");
        }

        redisLockUtils.tryLock(RedisLockPrefixEnum.REGISTER, sysUser.getUsername(), () -> {
            SysUser exist = Db.lambdaQuery(SysUser.class).eq(SysUser::getUsername, dto.getUsername()).one();
            if (exist != null) {
                sysUserManager.checkExist(exist.getId(), sysUser);

                sysUser.setId(exist.getId());
                sysUser.updateById();
            } else {
                sysUserManager.checkExist(null, sysUser);

                sysUser.insert();
            }

            SysTenantUser sysTenantUser = Db.lambdaQuery(SysTenantUser.class)
                    .eq(SysTenantUser::getTenantId, dto.getTenantId())
                    .eq(SysTenantUser::getUserId, sysUser.getId()).one();
            if (sysTenantUser == null) {
                new SysTenantUser(dto.getTenantId(), sysUser.getId()).insert();
            } else {
                sysTenantUser.setTenantId(dto.getTenantId());
                sysTenantUser.updateById();
            }
        });
    }

    @Override
    public void edit(SysUserEditDTO dto) {
        long userId = StpUtil.getLoginIdAsLong();
        SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
        sysUserManager.checkExist(userId, sysUser);

        sysUser.setId(userId);
        sysUser.updateById();
    }

    @Override
    public PageVO<SysUserVO> page(SysUserPageQuery query) {
        Page<SysUser> page = lambdaQuery()
                .like(StringUtils.isNotBlank(query.getUsername()), SysUser::getUsername, query.getUsername())
                .like(StringUtils.isNotBlank(query.getName()), SysUser::getName, query.getName())
                .like(StringUtils.isNotBlank(query.getMobile()), SysUser::getMobile, query.getMobile())
                .eq(query.getStatus() != null, SysUser::getStatus, query.getStatus())
                .eq(query.getRoleCode() != null, SysUser::getRoleCode, query.getRoleCode())
                .page(query.toPage());

        return new PageVO<>(page, SysUserVO.class);
    }

    @Override
    public SysUserVO getDetail(long userId) {
        SysUser sysUser = getById(userId);

        return BeanUtil.copyProperties(sysUser, SysUserVO.class);
    }

    @Override
    public void editPassword(SysUserPasswordDTO dto) {
        Db.lambdaQuery(SysUser.class).eq(SysUser::getId, StpUtil.getLoginIdAsLong()).oneOpt().ifPresent(sysUser -> {
            if (!Objects.equals(sysUser.getPassword(), UserUtils.passwordEncrypt(dto.getOldPassword()))) {
                throw new SysException("旧密码错误");
            }

            Db.lambdaUpdate(SysUser.class)
                    .eq(SysUser::getId, sysUser.getId())
                    .set(SysUser::getPassword, UserUtils.passwordEncrypt(dto.getNewPassword()))
                    .update();
        });
    }

    @Override
    public void audit(long userId, int status) {
        Db.lambdaUpdate(SysUser.class).eq(SysUser::getId, userId).set(SysUser::getStatus, status).update();
    }
    @Override
    public void revoked(long userId) {
        Db.removeById(userId, SysUser.class);
    }

}

